import { Role } from './../entitys/Role';
import { strToMd5 } from "../utils/utils"
import Page from "../common/page"
import * as moment from "moment"
import { getLog } from "../logger/logger"
import { Inject, Service } from "typedi"
import { User } from '../entitys/User'
import { getRepository, In } from 'typeorm'
import { YYYY_MM_DD_HH_MM_SS, YYYY_MM_DD } from "../utils/utils"
import { Context } from 'koa';
import CoutomError from '../common/CoutomError';
import { DeptService } from './DeptService';
interface Conds {
    username?: string
    phone?: string
    updateTimeRange?: string[]
    createTimeRange?: string[]
    roleCodes?: string[]
    deptId?: number
    page?: number
    pageSize?: number
}
interface UpdateParams {
    id: number
    username?: string
    nickname?: string
    deptId?: number
    phone?: string
    password?: string
    avatar?: string
    roleIds?: number[],
    dataStatus?: number
}
const logger = getLog("access")
@Service()
export default class UserService {
    @Inject()
    deptService: DeptService
    /**
     * 通过username获取用户
     * @param username
     */
    async selectUserByUsername(username: string) {
        //let [rows] = await pool.query("select id,username,password,phone,avatarfrom sys_user where username = ?",[username])
        //return rows
        const userRepository = getRepository(User)
        let user = await userRepository.
            createQueryBuilder("user").
            leftJoinAndSelect("user.roles", "role").
            leftJoinAndSelect("user.dept", "dept").where(`user.username = '${username}'`).andWhere("(role.dataStatus = 1 or role.dataStatus is null)").andWhere("user.dataStatus != -1").getOne()
        return user
    }
    async getUserById(id: number) {
        const userRepository = getRepository(User)
        // const user: any = await userRepository.findOne(id, { relations: ["roles", "dept"] })
        const user: any = await userRepository.
            createQueryBuilder("user").
            leftJoinAndSelect("user.roles", "role").
            leftJoinAndSelect("user.dept", "dept").where(`user.id = ${id}`).andWhere("(role.dataStatus = 1 or role.dataStatus is null)").andWhere("user.dataStatus != -1").getOne()
        if (user) {
            delete user.password
            user.createTime = moment(user.createTime).format(YYYY_MM_DD_HH_MM_SS)
            user.updateTime = moment(user.updateTime).format(YYYY_MM_DD_HH_MM_SS)
            user.roles.forEach((role: any) => {
                role.createTime = moment(role.createTime).format(YYYY_MM_DD_HH_MM_SS)
                role.updateTime = moment(role.updateTime).format(YYYY_MM_DD_HH_MM_SS)
            })
        }
        return user;
    }
    async changePassword(ctx: Context, password: string, newPassword: string) {
        const userRepository = getRepository(User)
        const user = await userRepository.findOne(ctx.userInfo.id)
        if (user.password !== strToMd5(password)) {
            throw new CoutomError("旧密码输入错误")
        }
        await userRepository.update(user.id, { password: strToMd5(newPassword) })
    }
    /**
     * 添加用户
     * @param username
     * @param password
     * @param phone
     * @param avatar
     */
    async addUser(username: string, password: string, nickname: string, phone: string, avatar: string, roleIds: number[]) {
        let pwd = strToMd5(password);
        let date = new Date()
        //await pool.execute("insert into sys_user (username,password,phone,avatal,update_time,create_time) values(?,?,?,?,?,?)",[username,pwd,phone,avatal,date,date])
        //return true
        let roles: Role[] = []
        if (roleIds) {
            const roleRepository = getRepository(Role)
            roles = await roleRepository.find({ id: In(roleIds) })
        }
        const userRepository = getRepository(User)
        const user = new User()
        user.username = username;
        user.password = password;
        user.nickname = nickname;
        user.phone = phone;
        user.avatar = avatar;
        user.createTime = new Date()
        user.updateTime = new Date()
        user.dataStatus = 1
        user.roles = roles
        let result = await userRepository.save(user)
        return result
    }
    /**
     * 根据不同条件查询用户 分页查询
     * @param params
     */
    async getUserByConds(params: Conds) {
        const userRepository = getRepository(User)
        const queryBuilder = userRepository.createQueryBuilder('user')
        queryBuilder.where("1=1").andWhere("user.dataStatus  in (0,1)")
        if (params.deptId) {
            queryBuilder.innerJoinAndSelect("user.dept", "dept").andWhere(`(dept.id = ${params.deptId} or dept.id in (select t.id from sys_dept t where find_in_set(${params.deptId},ancestors) ))`)
        }
        if (params.roleCodes) {
            let index = params.roleCodes.findIndex(s => s === '')
            if (index > -1) {
                params.roleCodes.splice(index, 1)
            }
            queryBuilder.innerJoinAndSelect("user.roles", 'role').andWhere("role.roleName in (:...roleCodes)", { roleCodes: params.roleCodes })
        }
        params.username && queryBuilder.andWhere(" user.username like :username", { username: "%" + params.username + "%" })
        params.phone && queryBuilder.andWhere(" user.phone = :phone ", { phone: params.phone })
        if (params.createTimeRange && params.createTimeRange instanceof Array) {
            queryBuilder.andWhere("user.createTime between :createStartTime and :createEndTime",
                {
                    createStartTime: moment(params.createTimeRange[0], YYYY_MM_DD).toDate(),
                    createEndTime: moment(params.createTimeRange[1], YYYY_MM_DD).toDate()
                })
        }
        if (params.updateTimeRange && params.updateTimeRange instanceof Array) {
            queryBuilder.andWhere(" user.updateTime between :updateStartTime and :updateEndTime",
                {
                    updateStartTime: moment(params.updateTimeRange[0], YYYY_MM_DD).toDate(),
                    updateEndTime: moment(params.updateTimeRange[1], YYYY_MM_DD).toDate()
                })
        }
        let count = await queryBuilder.getCount()
        let page = new Page(count, params.page, params.pageSize)
        let users = await queryBuilder.limit(page.pageSize).offset(page.startIndex).orderBy("user.updateTime", 'DESC').getMany()
        users.forEach((user: any) => {
            delete user.password
        })
        page.list = users
        return page
    }
    /**
     * 更新用户
     * @param params
     */
    async updateUser(params: UpdateParams) {
        const userRepository = getRepository(User)
        let user = await userRepository.findOne(params.id)
        params.username && (user.username = params.username)
        params.password && (user.password = strToMd5(params.password))
        params.phone && (user.phone = params.phone)
        params.avatar && (user.avatar = params.avatar)
        params.nickname && (user.nickname = params.nickname)
        if (params.deptId) {
            const dept = await this.deptService.getDeptById(params.deptId)
            user.dept = dept
        }
        user.updateTime = new Date()
        if ((params.dataStatus || params.dataStatus === 0) && (params.dataStatus >= 0 && params.dataStatus <= 1)) {
            user.dataStatus = params.dataStatus
        }
        if (params.roleIds) {
            const roleRepository = getRepository(Role)
            user.roles = await roleRepository.find({ id: In(params.roleIds) })
        }
        let result = await userRepository.save(user)
        return true

    }
    async getAllUser() {
        let userRepository = getRepository(User)
        let users = userRepository.find({ dataStatus: 1 })
        return users

    }
    async delUser(id: number) {
        const userRepository = getRepository(User)
        const user = await userRepository.findOne(id)
        if (!user) {
            throw Error("未找到指定用户")
        }
        user.roles = []
        user.dataStatus = -1
        userRepository.save(user)
    }
}
